#! /usr/bin/python

import urllib

import simplejson

# Shindig (see README) runs at this location by default.
# If you're trying it out, this is a good value to use.
# TODO(dbentley): it'd be great to have a running example people could see.
DEFAULT_SERVER = 'http://metzby.dyndns.info/social/rest/'


class UrllibResponse(object):
  """Response from UrlLib; used as a struct"""
  def __init__(self):
    pass


class UrllibFetcher(object):
  """A wrapper for urllib to make it look like urlfetch.

  This allows us to use either appengine's urlfetch or the normal urllib
  in the same library.

  There is much TODO left to make this more like urlfetch.  We'll do such
  work as it's necessary (or volunteered!).
  """
  def __init__(self):
    pass

  def fetch(self, url):
    response = UrllibResponse()
    # TODO(dbentley): remember status code
    response.content = urllib.urlopen(url).read()
    return response


class Client(object):
    """A client to OpenSocial Restful API's.

    member variables:
      _url_fetcher: a fetcher for URL's conformin to the urlfetch API
      _server_url: the url at which our OpenSocial API Container lives
    """
    def __init__(self, server_url, url_fetcher=None):
      """Create a Client.

      If url_fetcher is false, we use a default one.
      """
      # TODO(dbentley): here's a great place to clean up server_url
      # e.g., append http://, standardize to whether it ends with
      # a '/' or not, etc.
      self._url_fetcher = url_fetcher or UrllibFetcher()
      self._server_url = server_url


    def GetFriends(self, user_id):
      """Get a user's friends.

      Params:
        user_id: a str, the user's id on the container

      Returns:
        a list of friends

      TODO(dbentley): document the type of object returned as a friend,
      and create a type that encapsulates well
      """
      request_string = 'people/%s/@friends' % user_id
      response = self.GetRequest(request_string)
      return response['entry']

    def GetRequest(self, path, params=None):
      """A fairly low-level command to fetch information.

      Params:
        path: str, the path on the server to fetch.
        params: dict of str -> str, params to pass to the request

        TODO(dbentley): conceptually, if we want to work with servers that
          use different ways to express this information, how is the best way
          to expose this information?  If we want to do it by having some sort
          of representation of these as operations, don't we end up with some
          kind of 'fetch friends' operation object that takes parameters,
          and does that not then give back some of the utility of REST?

      Returns:
        the JSON returned to us
        TODO(dbentley): make this be something better
      """
      url = '%s%s' % (self._server_url, path)
      if params is not None:
        url = '%s?%s' % (url, urllib.urlencode(params))
      http_response = self._url_fetcher.fetch(url)
      # TODO(dbentley): here's a great place to turn the string
      # into some kind of objectual representation.
      response = simplejson.loads(http_response.content)
      return response
